﻿#include "VAOneXMLAdaptorMaterialFE.h"
#include "rapidxml.hpp"

#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialElastic.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialDensity.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialExpansion.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialDamping.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialBehavior.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterial.h"

#include "FITK_Kernel/FITKAppFramework/FITKComponents.h"
#include "FITK_Component/FITKNastranBDFIO/FITKNastranBDFIOInterface.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include <QDebug>

namespace IO
{
    bool VAOneXMLAdaptorMaterialFE::adaptR()
    {
        if(nullptr == _node || nullptr == _dataObj) return false;

        Interface::FITKAbaMaterial* materialPtr = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if(!materialPtr) return false;

        bool b = true;//数据读取状态 默认为true
        // 读取各项属性   // 每个属性可能存在缺省配置
        QString id = readStrAttribute(_node, "id", &b);
        if(b) materialPtr->setDataObjectName(id);//暂时没有存储地方（ID）存储到名字中

        QString name = readStrAttribute(_node, "name", &b);
        if(name.isEmpty())
        {
            consoleMessage(2, "FEMaterial name is null");//fe材料数据中 名称为必要项 不可为空 并抛出异常日志
            return false;
        }

        QString note = readStrAttribute(_node, "note", &b);
        if(b) materialPtr->setMaterialDescribe(note);

        double E = 0;
        double NU = 0;
        double RHO = 0;
        double A = 0;
        double TREF = 0;
        double GE = 0;
        double G = 0;
        int fieldIndex = 0;
        bool isOk = true;
        for (rapidxml::xml_node<char> *fieldNode = _node->first_node("FEfield");
             fieldNode; fieldNode = fieldNode->next_sibling())
        {
            double value = readDoubleNodeValue(fieldNode, &isOk);

            if(fieldIndex == 0)
            {
                //暂时没有存储地方（MAT1）
            }
            else if(fieldIndex == 1){}//暂时没有存储地方（MID）存储到名字中
            else if(fieldIndex == 2 && isOk)
                E = value;
            else if(fieldIndex == 3 && isOk)
                G = value;
            else if(fieldIndex == 4 && isOk)
                 NU = value;
            else if(fieldIndex == 5 && isOk)
                RHO = value;
            else if(fieldIndex == 6 && isOk)
                A = value;
            else if(fieldIndex == 7 && isOk)
                TREF = value;
            else if(fieldIndex == 8 && isOk)
                GE = value;
            fieldIndex++;
        }

        materialPtr->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Density);// 添加并设置材料行为：密度
        // 获取密度材料行为，并转换为FITKAbaMaterialDensity类型
        Interface::FITKAbaMaterialDensity* densityBehavior = dynamic_cast<Interface::FITKAbaMaterialDensity*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Density));
        if (nullptr != densityBehavior)
        {
            densityBehavior->setMassDensity(RHO);//设置质量密度
        }

        materialPtr->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Elastic);// 添加并设置材料行为：弹性
        Interface::FITKAbaMaterialElastic* materialBevior = dynamic_cast<Interface::FITKAbaMaterialElastic*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Elastic));
        if (nullptr != materialBevior)
        {
            materialBevior->setMaterialElasticType(Interface::FITKAbaMaterialBehaviorEnum::IsoTropic);
            materialBevior->setIsotropicYoungsModulus(E);// 设置杨氏模量
            materialBevior->setIsotropicPoissonRatio(NU);// 设置泊松比
        }

        materialPtr->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Expansion);// 添加并设置材料行为：膨胀
        Interface::FITKAbaMaterialExpansion* expensionBehavior = dynamic_cast<Interface::FITKAbaMaterialExpansion*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Expansion));
        if (nullptr != expensionBehavior)
        {
            expensionBehavior->setExpansionType(Interface::FITKAbaMaterialBehaviorEnum::Isotropic);
            expensionBehavior->setIsotropicTemperature(TREF);// 设置参考温度
            expensionBehavior->setIsoTropicExpansionCoeff(A);// 设置膨胀系数
        }

        materialPtr->addMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Damping);// 添加并设置材料行为：阻尼
        Interface::FITKAbaMaterialDamping* dampingBehavior = dynamic_cast<Interface::FITKAbaMaterialDamping*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Damping));
        if (nullptr != dampingBehavior)
        {
            dampingBehavior->setStructural(GE);// 设置结构阻尼
        }

        return b;// 返回操作是否成功
    }

    bool VAOneXMLAdaptorMaterialFE::adaptW()
    {
        if(nullptr == _node || nullptr == _dataObj) return false;

        Interface::FITKAbaMaterial* materialPtr = dynamic_cast<Interface::FITKAbaMaterial*>(_dataObj);
        if(nullptr == materialPtr) return false;

        // 写入各项属性
        writeAttribute(_node, "id", materialPtr->getDataObjectName());  // 传入 ID
        writeAttribute(_node, "name", QString("MAT1[%1]").arg(materialPtr->getDataObjectName()));  // 传入名称
        writeAttribute(_node, "note", materialPtr->getMaterialDescribe());  // 传入备注

        double E = 0;
        double NU = 0;
        double RHO = 0;
        double A = 0;
        double TREF = 0;
        double GE = 0;
        double G = 0;

        Interface::FITKAbaMaterialElastic* elasticBevior = dynamic_cast<Interface::FITKAbaMaterialElastic*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Elastic));
        if(elasticBevior)
        {
            E = elasticBevior->getIsotropicYoungsModulus();// 获取杨氏模量
            NU = elasticBevior->getIsotropicPoisssonRatio();// 获取泊松比
        }

        Interface::FITKAbaMaterialDensity* densityBehavior = dynamic_cast<Interface::FITKAbaMaterialDensity*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Density));

        if (nullptr != densityBehavior)
        {
            RHO = densityBehavior->getMassDensity();// 获取质量密度
        }

        Interface::FITKAbaMaterialExpansion* expensionBehavior = dynamic_cast<Interface::FITKAbaMaterialExpansion*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Expansion));

        if (nullptr != expensionBehavior)
        {
            TREF = expensionBehavior->getIsotropicTemperature();// 获取参考温度
            A = expensionBehavior->getIsotropicExpansionCoeff(); // 获取膨胀系数
        }

        Interface::FITKAbaMaterialDamping* dampingBehavior = dynamic_cast<Interface::FITKAbaMaterialDamping*>
                (materialPtr->getMaterialBehavior(Interface::FITKAbaMaterialBehaviorEnum::Damping));

        if (nullptr != dampingBehavior)
        {
            GE = dampingBehavior->getStructural();//获取阻尼结构
        }

        createNodeElement(_node, "FEfield", "MAT1");//MAT1 没有数据结构,暂时写死
        createNodeElement(_node, "FEfield", materialPtr->getDataObjectName());//MID 没有数据结构
        createNodeElement(_node, "FEfield", QString::number(E));
        createNodeElement(_node, "FEfield", QString::number(G));
        createNodeElement(_node, "FEfield", QString::number(NU));
        createNodeElement(_node, "FEfield", QString::number(RHO));
        createNodeElement(_node, "FEfield", QString::number(A));
        createNodeElement(_node, "FEfield", QString::number(TREF));
        createNodeElement(_node, "FEfield", QString::number(GE));
        // 数据写入成功
        return true;
    }

}
